#pragma once

#include "Storage.h"
#include <string>

namespace MockItNow
{
	class FunctionInfo;

	template<typename T>
	struct TypeInfo
	{
		typedef T StorageType;
		typedef std::string (*CompareFunction)(const Storage<T>&, const Storage<T>&);
	};

	template<>
	struct TypeInfo<void*>
	{
		typedef void* StorageType;
		typedef std::string (*CompareFunction)(const Storage<void*>&, const Storage<void*>&);
	};

	template<>
	struct TypeInfo<const void*>
	{
		typedef const void* StorageType;
		typedef std::string (*CompareFunction)(const Storage<const void*>&, const Storage<const void*>&);
	};

	template<typename T>
	struct TypeInfo<const T>
	{
		typedef T StorageType;
		typedef std::string (*CompareFunction)(const Storage<T>&, const Storage<T>&);
	};

	template<typename T>
	struct TypeInfo<T&>
	{
		typedef T StorageType;
		typedef std::string (*CompareFunction)(const Storage<T>&, const Storage<T>&);
	};

	template<typename T>
	struct TypeInfo<const T&>
	{
		typedef T StorageType;
		typedef std::string (*CompareFunction)(const Storage<T>&, const Storage<T>&);
	};

	template<typename T>
	struct TypeInfo<T*>
	{
		typedef T* StorageType;
		typedef std::string (*CompareFunction)(const Storage<T*>&, const Storage<T*>&);
	};

	template<typename T>
	struct TypeInfo<const T*>
	{
		typedef T* StorageType;
		typedef std::string (*CompareFunction)(const Storage<T*>&, const Storage<T*>&);
	};

	#define DECLARE_STORAGE_TYPE(FromType, ToType)												\
	template<>																					\
	struct TypeInfo<FromType>																	\
	{																							\
		typedef ToType StorageType;																\
		typedef std::string (*CompareFunction)(const Storage<ToType>&, const Storage<ToType>&);	\
	};																							\
																								\
	template<>																					\
	struct TypeInfo<FromType&>																	\
	{																							\
		typedef ToType StorageType;																\
		typedef std::string (*CompareFunction)(const Storage<ToType>&, const Storage<ToType>&);	\
	};																							\
																								\
	template<>																					\
	struct TypeInfo<const FromType&>															\
	{																							\
		typedef ToType StorageType;																\
		typedef std::string (*CompareFunction)(const Storage<ToType>&, const Storage<ToType>&);	\
	};
}
